From d9086b843d5da519fca876794d14026b14cc68ae Mon Sep 17 00:00:00 2001
Message-ID: <d9086b843d5da519fca876794d14026b14cc68ae.1689665371.git.stefan@agner.ch>
From: Stefan Agner <stefan@agner.ch>
Date: Mon, 5 Jun 2023 23:41:50 +0200
Subject: [PATCH] [rest] support deleting the dataset

Add REST API to support deleting the active or pending operational
dataset. Deleting the active operational dataset requires the Thread
network to be disabled (just like modifying the active operational
dataset). Subsequent use of the PUT method allows to build entirly
new datasets with values generated by the stack (through
otDatasetCreateNewNetwork).
---
 src/rest/openapi.yaml | 21 +++++++++++++++++++++
 src/rest/resource.cpp | 35 +++++++++++++++++++++++++++++++++++
 src/rest/resource.hpp |  1 +
 3 files changed, 57 insertions(+)

diff --git a/src/rest/openapi.yaml b/src/rest/openapi.yaml
index 2ba2a4dd56..2edc4af29a 100644
--- a/src/rest/openapi.yaml
+++ b/src/rest/openapi.yaml
@@ -248,6 +248,18 @@ paths:
           description: Invalid request body.
         "409":
           description: Writing active operational dataset rejected because Thread network is active.
+    delete:
+      tags:
+        - node
+      summary: Deletes the active operational dataset
+      description: |-
+        Deletes the the active operational dataset on the current node. Only allowed if the Thread node
+        is inactive.
+      responses:
+        "200":
+          description: Successfully deleted the active operational dataset.
+        "409":
+          description: Deleting active operational dataset rejected because Thread network is active.
   /node/dataset/pending:
     get:
       tags:
@@ -291,6 +303,15 @@ paths:
           description: Successfully created the pending operational dataset.
         "400":
           description: Invalid request body.
+    delete:
+      tags:
+        - node
+      summary: Deletes the pending operational dataset
+      description: |-
+        Deletes the the pending operational dataset on the current node.
+      responses:
+        "200":
+          description: Successfully deleted the active operational dataset.
 components:
   schemas:
     LeaderData:
diff --git a/src/rest/resource.cpp b/src/rest/resource.cpp
index a60e9d9483..829835341a 100644
--- a/src/rest/resource.cpp
+++ b/src/rest/resource.cpp
@@ -767,12 +767,47 @@ exit:
     }
 }
 
+void Resource::DeleteDataset(DatasetType aDatasetType, Response &aResponse) const
+{
+    otbrError                error       = OTBR_ERROR_NONE;
+    std::string              errorCode   = GetHttpStatus(HttpStatusCode::kStatusOk);
+    otOperationalDatasetTlvs datasetTlvs = {};
+
+    if (aDatasetType == DatasetType::kActive)
+    {
+        VerifyOrExit(otThreadGetDeviceRole(mInstance) == OT_DEVICE_ROLE_DISABLED, error = OTBR_ERROR_INVALID_STATE);
+    }
+
+    if (aDatasetType == DatasetType::kActive)
+    {
+        VerifyOrExit(otDatasetSetActiveTlvs(mInstance, &datasetTlvs) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
+    }
+    else if (aDatasetType == DatasetType::kPending)
+    {
+        VerifyOrExit(otDatasetSetPendingTlvs(mInstance, &datasetTlvs) == OT_ERROR_NONE, error = OTBR_ERROR_REST);
+    }
+    aResponse.SetResponsCode(errorCode);
+
+exit:
+    if (error == OTBR_ERROR_INVALID_STATE)
+    {
+        ErrorHandler(aResponse, HttpStatusCode::kStatusConflict);
+    }
+    else if (error != OTBR_ERROR_NONE)
+    {
+        ErrorHandler(aResponse, HttpStatusCode::kStatusInternalServerError);
+    }
+}
+
 void Resource::Dataset(DatasetType aDatasetType, const Request &aRequest, Response &aResponse) const
 {
     std::string errorCode;
 
     switch (aRequest.GetMethod())
     {
+    case HttpMethod::kDelete:
+        DeleteDataset(aDatasetType, aResponse);
+        break;
     case HttpMethod::kGet:
         GetDataset(aDatasetType, aRequest, aResponse);
         break;
diff --git a/src/rest/resource.hpp b/src/rest/resource.hpp
index d79085dbfc..362e501471 100644
--- a/src/rest/resource.hpp
+++ b/src/rest/resource.hpp
@@ -150,6 +150,7 @@ private:
     void GetDataRloc(Response &aResponse) const;
     void GetDataset(DatasetType aDatasetType, const Request &aRequest, Response &aResponse) const;
     void SetDataset(DatasetType aDatasetType, const Request &aRequest, Response &aResponse) const;
+    void DeleteDataset(DatasetType aDatasetType, Response &aResponse) const;
 
     void DeleteOutDatedDiagnostic(void);
     void UpdateDiag(std::string aKey, std::vector<otNetworkDiagTlv> &aDiag);
-- 
2.41.0

